#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "./func.c"

int plus_one(int n) {
  return n + 1;
}

// 传过来的值是拷贝而不是引用
void increment(int a) {
  a++;
}

int increment1(int a) {
  a++;
  return a;
}

// 这是无效的
void Swap(int x, int y) {
  int temp;
  temp = x;
  x = y;
  y = temp;
}

void Swap1(int* x, int* y) {
  int temp;
  temp = *x;
  *x = *y;
  *y = temp;
}

void print(int a) {
  printf("%d\n", a);
}

// 函数指针 指向函数 print 的地址
void (*print_ptr)(int) = &print;

unsigned long Fibonacci(unsigned n) {
  if (n > 2) {
    return Fibonacci(n - 1) + Fibonacci(n - 2);
  } else {
    return 1;
  }
}

// 函数原型
// c 语言必须要先声明函数才能调用
void func1(void) {

}

void func2(void) {

}


// 说明符,说明这个函数不在这个当前文件里
extern int func3(int arg1, char arg2);

// static 修饰符 
// 注意只能修饰常量
// 默认值为0
void counter(void) {
  static int count = 1; // 只初始化一次
  printf("%d\n", count);
  count++;
}
//修饰一个函数表示只能在这个文件里用
static int Twice(int num) {
  int result = num * 2;
  // return(result);
  return result;
}

// const修饰符
void f(const int* p) {
  // *p = 0; 报错无法修改 p 的值
  int x = 13;
  p = &x; // 允许修改
}

void f2(int* const p) {
  *p = 0; // p 的值可以修改了
  // int x = 13;
  // p = &x; 不允许修改
}

//可变参数
int myprint(const char* fotmat, ...) {
  return 0;
}

double average(int i, ...) {
  double total = 0;
  // 一个数据类型,定义一个可变参数对象
  va_list ap;
  // 初始化可变参数对象
  va_start(ap, i);
  for (int j = 1; j <= i; ++j) {
    // va_arg取出当前那个可变参数
    total += va_arg(ap, double);
  }
  // 清理可变参数对象
  va_end(ap);
  return total / i;
}

int main(void) {
  int a = plus_one(13);
  printf("%d\n", a);

  int i = 10;
  increment(i);
  printf("%d\n", i);

  (*print_ptr)(10);
  // 等同于
  print(10);
  // 其他三种写法
  (&print)(10);
  (*print)(10);
  print_ptr(10);

  // true
  if (print == &print) {
    //
  }

  func1();
  func2();
  int a1 = func3(2, 3);

  // 终止整个程序的运行
  // exit(EXIT_SUCCESS);
  counter();
  counter();
  counter();
  counter();

  return 0;
}